package com.lorizz.docrepo.repository.impl;

import javax.jcr.LoginException;
import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.nodetype.NodeDefinitionTemplate;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.NodeTypeTemplate;

import com.lorizz.docrepo.DocrepoException;

public class JcrDocumentRepositoryInitializer {

    protected String adminId;
    protected Repository repository;
    protected Session session;

    public void setAdminId(String adminId) {
        this.adminId = adminId;
    }

    public void setRepository(Repository repository) {
        this.repository = repository;
    }

    protected Session getSession() {
        try {
            if (session == null || !session.isLive())
                session = repository.login(new SimpleCredentials(adminId, ""
                        .toCharArray()));
            return session;
        } catch (LoginException e) {
            throw new DocrepoException(e);
        } catch (RepositoryException e) {
            throw new DocrepoException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public void init() throws RepositoryException {
        // namespace
        NamespaceRegistry namespaceRegistry = getSession().getWorkspace()
                .getNamespaceRegistry();
        if (!isNamespacePrefixRegistered(namespaceRegistry)) {
            namespaceRegistry.registerNamespace(
                    JcrDocumentRepositoryConstants.NAMESPACE,
                    JcrDocumentRepositoryConstants.NAMESPACE_URI);
        }
        // nodetypes
        NodeTypeManager ntm = getSession().getWorkspace().getNodeTypeManager();

        // document
        NodeTypeTemplate ntDocument = ntm.createNodeTypeTemplate();
        ntDocument.setName(JcrDocumentRepositoryConstants.NT_DOCUMENT);
        ntDocument.setQueryable(true);
        ntDocument.setDeclaredSuperTypeNames(new String[] { NodeType.NT_FILE,
                NodeType.MIX_TITLE, NodeType.MIX_CREATED,
                NodeType.MIX_REFERENCEABLE, NodeType.MIX_SIMPLE_VERSIONABLE });
        NodeDefinitionTemplate nResource = ntm.createNodeDefinitionTemplate();
        nResource
                .setRequiredPrimaryTypeNames(new String[] { NodeType.NT_RESOURCE });
        nResource.setDefaultPrimaryTypeName(NodeType.NT_RESOURCE);
        nResource.setMandatory(true);
        nResource.setName("*");
        ntDocument.getNodeDefinitionTemplates().add(nResource);
        ntm.registerNodeType(ntDocument, true);

        // folder
        NodeTypeTemplate ntFolder = ntm.createNodeTypeTemplate();
        ntFolder.setName(JcrDocumentRepositoryConstants.NT_FOLDER);
        ntFolder.setQueryable(true);
        ntFolder.setDeclaredSuperTypeNames(new String[] { NodeType.NT_FOLDER,
                NodeType.MIX_TITLE, NodeType.MIX_CREATED,
                NodeType.MIX_SHAREABLE });
        NodeDefinitionTemplate nDocument = ntm.createNodeDefinitionTemplate();
        nDocument
                .setRequiredPrimaryTypeNames(new String[] { JcrDocumentRepositoryConstants.NT_DOCUMENT });
        nDocument
                .setDefaultPrimaryTypeName(JcrDocumentRepositoryConstants.NT_DOCUMENT);
        nDocument.setName("*");
        nDocument.setSameNameSiblings(false);
        NodeDefinitionTemplate nFolder = ntm.createNodeDefinitionTemplate();
        nFolder.setRequiredPrimaryTypeNames(new String[] { JcrDocumentRepositoryConstants.NT_FOLDER });
        nFolder.setDefaultPrimaryTypeName(JcrDocumentRepositoryConstants.NT_FOLDER);
        nFolder.setName("*");
        nFolder.setSameNameSiblings(false);
        ntFolder.getNodeDefinitionTemplates().add(nDocument);
        ntFolder.getNodeDefinitionTemplates().add(nFolder);
        ntm.registerNodeType(ntFolder, true);
    }

    private boolean isNamespacePrefixRegistered(NamespaceRegistry registry)
            throws RepositoryException {
        try {
            registry.getURI(JcrDocumentRepositoryConstants.NAMESPACE);
            return true;
        } catch (NamespaceException e) {
            return false;
        }

    }

}
